package com.cn.jinhao.hotline.provider.huawu.job;

import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.net.url.UrlPath;
import cn.hutool.core.net.url.UrlQuery;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.db.Db;
import cn.hutool.db.DbUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import cn.hutool.db.ds.druid.DruidDSFactory;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.setting.Setting;
import org.apache.commons.lang3.StringUtils;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class QueueJob {
    private static final Log log = LogFactory.get();
    private static final Setting setting = new Setting("config/huawu.setting");
    private static final int retry_max = setting.getInt("retry.times.max", "huawu", 10);
    private static final DataSource ds = DSFactory.get();
    private UrlBuilder urlBuilder = UrlBuilder.create();
    private String url = null;

    private QueueJob() {
    }

    private String startCti(String aid, String adn) throws Exception {
        HashMap<String,String> startMap = new HashMap<>(6);
        startMap.put("dom", "");
        startMap.put("eid","0");
        startMap.put("epwd","");
        startMap.put("aid",aid);
        startMap.put("apwd","");
        startMap.put("adn",adn);
        JSONObject startJson = JSONUtil.parseObj(startMap);

        boolean startFinished = false;
        int times = 1;
        while(!startFinished && times <= retry_max) {
            HttpResponse response = HttpRequest.post(this.getStartUrl()).body(startJson.toStringPretty()).execute();
            if (response.getStatus() != HttpStatus.HTTP_OK) {
                log.error("OpenApi启动接口调用失败!");
                times++;
            }else {
                startFinished = true;
            }

            if (times == retry_max) {
                throw new Exception("启动接口调用失败次数已经达到上限....");
            }
            JSONObject jsonObject = new JSONObject(response.body());
            return jsonObject.getStr("token");
        }
        return null;
    }

    private void logoutCti(String token, String aid) throws Exception {
        HashMap<String, String> logoutMap = new HashMap<>(3);
        logoutMap.put("dom", "");
        logoutMap.put("token", token);
        logoutMap.put("aid", aid);
        JSONObject logoutJson = JSONUtil.parseObj(logoutMap);

        boolean logoutFinished = false;
        int times = 1;
        while(!logoutFinished && times <= retry_max) {
            HttpResponse response = HttpRequest.post(this.getLogoutUrl()).body(logoutJson.toStringPretty()).execute();
            if (response.getStatus() != HttpStatus.HTTP_OK) {
                log.error("OpenApi坐席签出接口调用失败!");
                times++;
            }else {
                logoutFinished = true;
            }

            if (times == retry_max) {
                throw new Exception("坐席签出接口调用失败次数已经达到上限....");
            }
        }
    }

    private void exitCti(String token) throws Exception {
        // 接口调用失败，尝试10次重调，10次失败后抛出异常
        HashMap<String,String> exitMap = new HashMap<>(2);
        exitMap.put("dom","");
        exitMap.put("token",token);
        JSONObject exitJson = JSONUtil.parseObj(exitMap);

        boolean exitFinished = false;
        int times = 1;
        while(!exitFinished && times <= retry_max) {
            HttpResponse response = HttpRequest.post(this.getExitUrl()).body(exitJson.toStringPretty()).execute();
            if (response.getStatus() != HttpStatus.HTTP_OK) {
                log.error("OpenApi退出接口调用失败！");
                times++;
            } else {
                exitFinished = true;
            }
        }
        if (times == retry_max) {
            throw new Exception("退出接口调用失败次数已经达到上限......");
        }
    }

    private String getStartUrl() throws Exception{
        this.getPostUrl("url.start.path");
        return urlBuilder.toString();
    }

    private String getExitUrl() throws Exception {
        this.getPostUrl("url.exit.path");
        return urlBuilder.toString();
    }

    private String getLogoutUrl() throws Exception {
        this.getPostUrl("url.logout.path");
        return urlBuilder.toString();
    }

    private UrlQuery initQuery(String queryName, String queryValue) throws Exception{
        HashMap<String, Object> paramsMap = this.getParams(queryName, queryValue);
        String[] keys = (String[]) paramsMap.get("keys");
        String[] values = (String[]) paramsMap.get("values");
        StringBuilder result = new StringBuilder().append(keys[0]).append("=").append(values[0]);
        for(int i = 1;i<keys.length;i++) {
            result.append("&").append(keys[i]).append("=").append(values[i]);
        }
        return UrlQuery.of(result.toString(), CharsetUtil.CHARSET_UTF_8);
    }

    private HashMap<String,String> getbody(String postName, String postValue) throws Exception {
        HashMap<String, Object> paramsMap = this.getParams(postName, postValue);
        String[] keys = (String[]) paramsMap.get("keys");
        String[] values = (String[]) paramsMap.get("values");
        HashMap<String, String> resultMap = new HashMap<>(10);
        for(int i = 0;i<keys.length;i++) {
            resultMap.put(keys[i],values[i]);
        }
        return resultMap;
    }

    private HashMap<String, Object> getParams(String keyName, String valueName) throws Exception {
        HashMap<String, Object> resultMap = new HashMap<>(2);
        String[] keys = setting.getByGroup(keyName,"huawu").split(",");
        String[] values = setting.getByGroup(valueName,"huawu").split(",");

        if (keys.length != values.length) {
            log.error("请求参数个数不一致，请检查!");
            throw new Exception("请求参数个数不一致，请检查!");
        }
        resultMap.put("keys", keys);
        resultMap.put("values", values);
        return resultMap;

    }

    private void getGetUrl(UrlQuery query, String path) {
        this.getPostUrl(path);
        urlBuilder.setQuery(query);
    }

    private void getPostUrl(String path) {
        urlBuilder.setScheme(setting.getStr("url.scheme", "huawu", "http"));
        urlBuilder.setHost(setting.getStr("url.host", "huawu", "127.0.0.1"));
        urlBuilder.setPath(UrlPath.of(setting.getByGroup(path, "huawu"), CharsetUtil.CHARSET_UTF_8));
        urlBuilder.setPort(Integer.parseInt(setting.getStr("url.port", "huawu", "8080")));
    }

    public void kickOutQueue() {
        try {
//            initUrl();
//            DSFactory.setCurrentDSFactory(new DruidDSFactory());
//            DataSource ds = DSFactory.get();
//            Db db = Db.use(ds);

//            String startUrl = this.getStartUrl();
//            HttpResponse startResponse = HttpRequest.post(url).body(jsonBody).execute();
            List<Entity> results = Db.use().findAll(Entity.create("TB_CTI_SEAT_INFO").set("STATUS", 1));
            results.forEach(entity -> {
                try {
                    String seatCode = entity.get("SEAT_NO").toString();
                    String seatPhone = entity.get("SEAT_PHONE").toString();
                    //与CTI建立连接并获取token
                    String token = this.startCti(seatCode, seatPhone);
                    // 坐席签出
                    this.logoutCti(seatCode, token);
                    // 退出CTI
                    this.exitCti(token);

                } catch (Exception e) {
                    e.printStackTrace();
                }

                // 坐席从队列踢出后把数据库里的坐席队列状态修改
                try {
//                    Db.use().update(
//                        Entity.create().set("STATUS", 1).set("UPDATED_TIME",new Date()),
//                        Entity.create("TB_CTI_SEAT_INFO").set("ID", entity.get("ID").toString())
//                    );
                    Db.use().del(Entity.create("TB_CTI_SEAT_INFO").set("ID", entity.get("ID").toString()));
                } catch (SQLException e) {
                    log.error(e, "更新话务队列状态失败!");
                    e.printStackTrace();
                }
            });
        }catch (SQLException sqlEx) {
            log.error(sqlEx, "SQL Statement error!");
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            DbUtil.close();
        }
    }
}
